home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 18 / develop 18 code / OSA Sample / Sources / Application.cp < prev    next >
Encoding:
Text File  |  1994-01-28  |  12.8 KB  |  535 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        Application.cp
  3.  
  4.     Contains:    TApplication implementation.
  5.  
  6.     This module derived from the Apple Shared Library Manager
  7.     sample source code supplied with ASLM 1.1 (note that ASLM
  8.     is NOT required for, or used in, this project).
  9.     
  10.     Developed by:    
  11.         
  12.         Paul G Smith (commstalk hq & Full Moon Software, Inc)
  13.         
  14.         you can leave messages at (UK): 0727 844232; (US): 408 253 7199
  15.         BUT I prefer to be contacted by e-mail
  16.         AppleLink:     SMITH.PG
  17.         Internet:     SMITH.PG@applelink.apple.com
  18.         
  19.         "SimpliFace" Sample code to accompany develop article
  20.         on techniques for embedding scripts in applications.
  21.  
  22. */
  23.  
  24. #ifndef __TYPES__
  25. #include <Types.h>
  26. #endif
  27.  
  28. #if MACOS
  29. #ifndef __QUICKDRAW__
  30. #include <QuickDraw.h>
  31. #endif
  32. #endif
  33.  
  34. #ifndef __FONTS__
  35. #include <Fonts.h>
  36. #endif
  37. #ifndef __EVENTS__
  38. #include <Events.h>
  39. #endif
  40. #ifndef __WINDOWS__
  41. #include <Windows.h>
  42. #endif
  43. #ifndef __MENUS__
  44. #include <Menus.h>
  45. #endif
  46. #ifndef __DIALOGS__
  47. #include <Dialogs.h>
  48. #endif
  49. #ifndef __TOOLUTILS__
  50. #include <ToolUtils.h>
  51. #endif
  52. #ifndef __MEMORY__
  53. #include <Memory.h>
  54. #endif
  55. #ifndef __SEGLOAD__
  56. #include <SegLoad.h>
  57. #endif
  58. #ifndef __OSUTILS__
  59. #include <OSUtils.h>
  60. #endif
  61. #ifndef __TRAPS__
  62. #include <Traps.h>
  63. #endif
  64.  
  65. #ifndef __APPLICATION__
  66. #include <Application.h>
  67. #endif
  68. #ifndef __APPLICATIONCOMMON__
  69. #include "ApplicationCommon.h"
  70. #endif
  71.  
  72. #include "TrapAvailable.cp"
  73.  
  74. // OSEvent is the event number of the suspend/resume and mouse-moved events sent
  75. // by MultiFinder. Once we determine that an event is an osEvent, we look at the
  76. // high byte of the message sent to determine which kind it is. To differentiate
  77. // suspend and resume events we check the resumeMask bit.
  78. const short kOsEvent = app4Evt;                // event used by MultiFinder
  79. const short kSuspendResumeMessage = 0x01;    // high byte of suspend/resume event message
  80. const short kClipConvertMask = 0x02;        // bit of message field clip conversion
  81. const short kResumeMask = 0x01;                // bit of message field for resume vs. suspend
  82. const short kMouseMovedMessage = 0xFA;        // high byte of mouse-moved event message
  83.  
  84. /*******************************************************************************
  85. ** PUBLIC Constructor/Destructor
  86. ********************************************************************************/
  87.  
  88. TApplication::TApplication()
  89. {
  90.     fDone = NULL;
  91.     fInBackground = false;
  92.     fMouseRgn = NULL;
  93.     fWhichWindow = NULL;
  94.     fqd = NULL;
  95. }
  96.  
  97. TApplication::TApplication(Ptr qdPtr)
  98. {
  99.     InitApplication(qdPtr);
  100. }
  101.  
  102. TApplication::~TApplication(void)
  103. {
  104. }
  105.  
  106. /*******************************************************************************
  107. ** PRIVATE InitApplication
  108. ********************************************************************************/
  109.  
  110. void TApplication::InitApplication(Ptr qdPtr)
  111. {
  112.     SysEnvRec envRec;
  113.     long stkNeeded, heapSize;
  114.     fqd = (qdRec*)qdPtr;
  115.  
  116.     // initialize Mac Toolbox components
  117.     InitGraf(&fqd->thePort);
  118.     InitFonts();
  119.     InitWindows();
  120.     InitMenus();
  121.     TEInit();
  122.     InitDialogs(NULL);
  123.     InitCursor();
  124.  
  125.     // ignore the error returned from SysEnvirons; even if an error occurred,
  126.     // the SysEnvirons glue will fill in the SysEnvRec
  127.     (void) SysEnvirons(curSysEnvVers, &envRec);
  128.  
  129.     // Are we running on a 128K ROM machine or better???
  130.     if (envRec.machineType < 0) {
  131.         TApplication::BigBadError(kApplicationErrStrings,eWrongMachine); // if not, alert & quit
  132.     }
  133.  
  134.     // if we need more stack space, get it now
  135.     stkNeeded = StackNeeded();
  136.     if (stkNeeded > StackSpace())
  137.       {
  138.         // new address is heap size + current stack - needed stack
  139.         SetApplLimit((Ptr) ((long) GetApplLimit() - stkNeeded + StackSpace()));
  140.       }
  141.  
  142.     // Check for minimum heap size
  143.     heapSize = (long) GetApplLimit() - (long) ApplicZone();
  144.     if (heapSize < HeapNeeded()) {
  145.         TApplication::BigBadError(kApplicationErrStrings,eSmallSize);
  146.     }
  147.  
  148.     // expand the heap so new code segments load at the top
  149.     MaxApplZone();
  150.  
  151.     // allocate an empty document list
  152.     // fDocList = new TDocumentList;
  153.  
  154.     // initialize our class variables
  155.     fDone = false;
  156.     fInBackground = false;
  157.     fMouseRgn = NULL;
  158.     fWhichWindow = NULL;
  159. }
  160.  
  161. /**********************************************************************
  162. ** PUBLIC EventLoop
  163. ***********************************************************************/
  164.  
  165.  
  166. Boolean TApplication::HandleEvent(EventRecord& /*theEvent*/, Boolean& /*pass*/)
  167. {
  168.     return false;
  169. }
  170.  
  171. void TApplication::InEventLoop(void)
  172. {
  173.     Boolean gotEvent;
  174.     EventRecord tEvt;
  175.     Boolean pass = false;
  176.     WindowPtr oldWindow;
  177.     
  178.     GetPort(&oldWindow);
  179.  
  180.     // always set up fWhichWindow before doing anything
  181.     fWhichWindow = FrontWindow();
  182.     // make sure we always draw into correct window
  183.     if (fWhichWindow)
  184.         SetPort(fWhichWindow);
  185.  
  186.     DoIdle();            // call idle time handler
  187.     
  188.     gotEvent = WaitNextEvent(everyEvent, &tEvt, SleepVal(), fMouseRgn);
  189.     fTheEvent = tEvt;
  190.  
  191.     // make sure we got a real event
  192.     if ( gotEvent && !HandleEvent(tEvt, pass))
  193.       {
  194.         AdjustCursor();
  195.         switch (tEvt.what)
  196.           {
  197.             case mouseDown :
  198.                 DoMouseDown();
  199.                 break;
  200.             case mouseUp :
  201.                 DoMouseUp();
  202.                 break;
  203.             case keyDown :
  204.             case autoKey :
  205.                 DoKeyDown();
  206.                 break;
  207.             case updateEvt :
  208.                 DoUpdateEvt();                
  209.                 break;
  210.             case diskEvt :
  211.                 DoDiskEvt();
  212.                 break;
  213.             case activateEvt :
  214.                 DoActivateEvt();
  215.                 break;
  216.             case kOsEvent :
  217.                 DoOSEvent();
  218.                 break;
  219.             case kHighLevelEvent:
  220.                 DoHighLevelEvent();
  221.                 break;
  222.             default :
  223.                 break;
  224.           } // end switch (fTheEvent.what)
  225.       }
  226.     AdjustCursor();
  227.  
  228.     SetPort(oldWindow);
  229. }
  230.  
  231. void TApplication::EventLoop(void)
  232. {
  233.     SetUp();                    // call setup routine
  234.     DoIdle();                    // do idle once
  235.  
  236.     while (fDone == false)
  237.     {
  238.         InEventLoop();
  239.     }
  240.     // call cleanup handler
  241.     CleanUp();
  242. }
  243.  
  244. /**********************************************************************
  245. ** PUBLIC StackNeeded/HeapNeeded
  246. ***********************************************************************/
  247.  
  248. long TApplication::StackNeeded()
  249. {
  250.     return 0;
  251. }
  252.  
  253. long TApplication::HeapNeeded()
  254. {
  255.     return 0;
  256. }
  257.  
  258. /**********************************************************************
  259. ** PUBLIC SetUp/Cleanup
  260. ***********************************************************************/
  261.  
  262. void TApplication::SetUp()
  263. {
  264.     // Run before event loop starts
  265. }
  266.  
  267. void TApplication::CleanUp()
  268. {
  269.     // run at end of loop
  270. }
  271.  
  272. /**********************************************************************
  273. ** PUBLIC ExitLoop
  274. ***********************************************************************/
  275.  
  276. void TApplication::ExitLoop(void)
  277. {
  278.     this->fDone = true;
  279. }
  280.  
  281. /**********************************************************************
  282. ** PUBLIC DoIdle
  283. ***********************************************************************/
  284.  
  285. void TApplication::DoIdle()
  286. {
  287.     // idle time handler (blink caret, background tasks)
  288. }
  289.  
  290. /**********************************************************************
  291. ** PUBLIC AdjustMenus
  292. ***********************************************************************/
  293.  
  294. void TApplication::AdjustMenus()
  295. {
  296.     // menu updater routine
  297. }
  298.  
  299. /**********************************************************************
  300. ** PUBLIC DoKeyDown
  301. ***********************************************************************/
  302.  
  303. void TApplication::DoKeyDown(void)
  304. {
  305.     char key;
  306.     long mResult;
  307.  
  308.     key = (char) (fTheEvent.message & charCodeMask);
  309.     if ((fTheEvent.modifiers & cmdKey) && (fTheEvent.what == keyDown))
  310.     {
  311.         // only do command keys if we are not autokeying
  312.         AdjustMenus();                    // make sure menus are up to date
  313.         mResult = MenuKey(key);
  314.         if (mResult != 0)                // if it wasn't a menu key, pass it through
  315.         {
  316.             DoMenuCommand(HiWord(mResult), LoWord(mResult));
  317.             return;
  318.         }
  319.     }
  320. }
  321.  
  322. /**********************************************************************
  323. ** PUBLIC DoHighLevelEvent
  324. ***********************************************************************/
  325. void TApplication::DoHighLevelEvent(void)
  326. {
  327.     EventRecord tEvt = fTheEvent;
  328.     // we copy event record so that we don't pass reference to object field 
  329.  
  330.     AEProcessAppleEvent(&tEvt);
  331. }
  332.  
  333.  
  334.  
  335. /**********************************************************************
  336. ** PUBLIC DoActivateEvt/DoUpdateEvt
  337. ***********************************************************************/
  338.  
  339. void TApplication::DoActivateEvt(void)
  340. {
  341.     // event record contains window ptr
  342.     fWhichWindow = (WindowPtr) fTheEvent.message;
  343.     SetPort(fWhichWindow);
  344.     
  345. }
  346.  
  347. void TApplication::DoUpdateEvt(void)
  348. {
  349.     // event record contains window ptr
  350.     fWhichWindow = (WindowPtr) fTheEvent.message;
  351.  
  352.     SetPort(fWhichWindow);
  353. }
  354.  
  355. /**********************************************************************
  356. ** PUBLIC DoOSEvent
  357. ***********************************************************************/
  358.  
  359. void TApplication::DoOSEvent(void)
  360. {
  361.     Boolean doConvert;
  362.     unsigned char evType;
  363.  
  364.     // is it a multifinder event?
  365.     evType = (unsigned char) (fTheEvent.message >> 24) & 0x00ff;
  366.     switch (evType) {     // high byte of message is type of event
  367.         case kMouseMovedMessage :
  368.             DoIdle();                    // mouse-moved is also an idle event
  369.             break;
  370.         case kSuspendResumeMessage :
  371.             doConvert = (fTheEvent.message & kClipConvertMask) != 0;
  372.             fInBackground = (fTheEvent.message & kResumeMask) == 0;
  373.             if (fInBackground)
  374.               DoSuspend(doConvert);
  375.             else DoResume(doConvert);
  376.             break;
  377.     }
  378. }
  379.  
  380. /**********************************************************************
  381. ** PUBLIC DoMouseDown
  382. ***********************************************************************/
  383.  
  384. void TApplication::DoMouseDown(void)
  385. {
  386.     long mResult;
  387.     short partCode;
  388.     WindowPtr tWind;
  389.     EventRecord tEvt;
  390.  
  391.     // gotta watch those object field dereferences
  392.     partCode = FindWindow(fTheEvent.where, &tWind);
  393.     fWhichWindow = tWind;
  394.     tEvt = fTheEvent;
  395.     switch (partCode)
  396.       {
  397.         case inSysWindow :
  398.             DoMouseInSysWindow();
  399.             break;
  400.         case inMenuBar :
  401.             AdjustMenus();
  402.             mResult = MenuSelect(tEvt.where);
  403.             if (mResult != 0)
  404.               DoMenuCommand(HiWord(mResult),LoWord(mResult));
  405.             break;
  406.         case inGoAway :
  407.             DoGoAway();                    
  408.             break;
  409.         case inDrag :
  410.             DoDrag();
  411.             break;
  412.         case inGrow :
  413.             break;
  414.         case inZoomIn :
  415.         case inZoomOut :
  416.             break;
  417.         case inContent :
  418.             // If window is not in front, make it so
  419.             if ( fWhichWindow != FrontWindow() )
  420.               SelectWindow(fWhichWindow);
  421.             break;
  422.       }
  423. }
  424.  
  425. /**********************************************************************
  426. ** PUBLIC DoMouseInSysWindow
  427. ***********************************************************************/
  428.  
  429. void TApplication::DoMouseInSysWindow()
  430. {
  431.     SystemClick(&fTheEvent, fWhichWindow);
  432. }
  433.  
  434. /**********************************************************************
  435. ** PUBLIC DoDrag
  436. ***********************************************************************/
  437.  
  438. void TApplication::DoDrag(void)
  439. {
  440.     DragWindow(fWhichWindow, fTheEvent.where, &fqd->screenBits.bounds);
  441. }
  442.  
  443. /**********************************************************************
  444. ** PUBLIC DoGoAway
  445. ***********************************************************************/
  446.  
  447. void TApplication::DoGoAway(void)
  448. {
  449.     if (TrackGoAway(fWhichWindow, fTheEvent.where)) {
  450.         CloseDeskAcc(((WindowPeek) fWhichWindow)->windowKind);
  451.  
  452.         fWhichWindow = FrontWindow();
  453.         if (fWhichWindow != NULL) {
  454.             SetPort(fWhichWindow);
  455.         }
  456.     }
  457. }
  458.  
  459. /**********************************************************************
  460. ** PUBLIC AdjustCursor
  461. ***********************************************************************/
  462.  
  463. void TApplication::AdjustCursor()
  464. {
  465.     // cursor adjust routine, should setup mouseRgn
  466. }
  467.  
  468. /**********************************************************************
  469. ** PUBLIC DoMenuCommand
  470. ***********************************************************************/
  471.  
  472. void TApplication::DoMenuCommand(short, short)
  473. {
  474. }
  475.  
  476. /**********************************************************************
  477. ** PUBLIC DoSuspend/DoResume
  478. ***********************************************************************/
  479.  
  480. void TApplication::DoSuspend(Boolean /*doClipConvert*/)
  481. {
  482. }
  483.  
  484. void TApplication::DoResume(Boolean /*doClipConvert*/)
  485. {
  486. }
  487.  
  488. /**********************************************************************
  489. ** PUBLIC DoMenuCommand
  490. ***********************************************************************/
  491.  
  492. void TApplication::DoMouseUp()
  493. {
  494. }
  495.  
  496. /**********************************************************************
  497. ** PUBLIC DoDiskEvt
  498. ***********************************************************************/
  499.  
  500. void TApplication::DoDiskEvt()
  501. {
  502. }
  503.  
  504. /**********************************************************************
  505. ** PUBLIC SleepVal
  506. ***********************************************************************/
  507.  
  508. unsigned long TApplication::SleepVal()
  509. {
  510.     return 20;        // how long to sleep in WaitNextEvent
  511. }
  512.  
  513. /**********************************************************************
  514. **  TApplication static methods
  515. ***********************************************************************/
  516.  
  517. void TApplication::AlertUser(short errResID, short errCode)
  518. {
  519.     Str255 message;
  520.  
  521.     GetIndString(message, errResID, errCode);
  522.     #if qDebug
  523.     if (message[0] == 0)
  524.         DebugStr((ConstStr255Param)"\pTApplication::AlertUser could not get error string.");
  525.     #endif
  526.     ParamText(message, (ConstStr255Param)"\p", (ConstStr255Param)"\p", (ConstStr255Param)"\p");
  527.     (void) Alert(rUserAlert, NULL);
  528. }
  529.  
  530. void TApplication::BigBadError(short errResID, short errCode)
  531. {
  532.     TApplication::AlertUser(errResID,errCode);
  533.     ExitToShell();
  534. }
  535.